package com.tfr.core.utility;

import java.util.ArrayList;

import org.apache.commons.lang3.StringUtils;
import org.htmlparser.Parser;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

import com.tfr.core.dataelements.Actor;
import com.tfr.core.dataelements.Cast;
import com.tfr.core.dataelements.Movie;

public class WikiUtility {

	/*This method sets the extracted data to Movie object.
	 * 
	 */
	
	public static Movie getMovieFromWikiData(
			ArrayList<ArrayList<String>> listOfLabelsAndValues) {
		Movie m = new Movie();
		String name = listOfLabelsAndValues.get(0).get(0).toString();
		m.setName(name);
		for (ArrayList<String> singleLabelAndValue : listOfLabelsAndValues) {

			if (singleLabelAndValue != null && !singleLabelAndValue.isEmpty()) {
				String label = singleLabelAndValue.get(0);
				String value = singleLabelAndValue.size() > 1 ? singleLabelAndValue
						.get(1).toString().trim()
						: "";
				value = StringUtils.strip(value, ",");
				if (label.equals("Directed by")) {
					m.setDirector(value);
				} else if (label.equals("Starring")) {
					Cast cast = new Cast();

					int i = 0;
					String tmp = "";
					for (String tag : value.split(",")) {
						if (i == 0)
							cast.setHero(tag);
						if (i == 1)
							cast.setHeroine(tag);
						if (i >= 2) {
							tmp = tmp + " , " + tag;
							cast.setOther(tmp);
						}
						i++;
					}
					m.setCast(cast);
				} else if (label.equals("Produced by")) {
					m.setProducer(value);
				} else if (label.equals("Written by")) {
					m.setWriter(value);
				} else if (label.equals("Music by")) {
					m.setMusicDirector(value);
				} else if (label.equals("Cinematography")) {
					m.setCinematography(value);
				} else if (label.equals("Distributed by")) {
					m.setDistributor(value);
				} else if (label.equals("Editing by")) {
					m.setEditor(value);
				} else if (label.equals("Studio")) {
					m.setStudio(value);
				} else if (label.equals("Running time")) {
					m.setRunningTime(value);
				} else if (label.equals("Country")) {
					m.setCountry(value);
				} else if (label.equals("Language")) {
					m.setLanguage(value);
				} else if (label.equals("Budget")) {
					m.setBudget(value);
				} else if (label.equals("Box office")) {
					m.setBoxOffice(value);
				} else if (label.startsWith("Release")) {
					m.setReleaseDate(value);
				}
			}
		}

		return m;
	}

	/*This method sets the extracted data to actor object.
	 * 
	 */
	public static Actor getActorFromWikiData(
			ArrayList<ArrayList<String>> listOfLabelsAndValues) {
		Actor actor = new Actor();
		String name[] = listOfLabelsAndValues.get(0).get(0).split(",");
		actor.setRealName(name[0]);
		for (ArrayList<String> singleLabelAndValue : listOfLabelsAndValues) {

			if (singleLabelAndValue != null && !singleLabelAndValue.isEmpty()) {
				String label = singleLabelAndValue.get(0);
				String value = singleLabelAndValue.size() > 1 ? singleLabelAndValue
						.get(1).toString().trim()
						: "";
				value = StringUtils.strip(value, ",");
				if (label.equals("Born")) {
					actor.setBorn(value);
				} else if (label.equals("Occupation")) {
					actor.setOccupation(value);
				} else if (label.equals("Residence")) {
					actor.setResidence(value);
				} else if (label.equals("Education")) {
					actor.setEducation(value);
				} else if (label.equals("Other names")) {
					actor.setAliasName(value);
				} else if (label.equals("Years active")) {
					actor.setYearsActive(value);
				} else if (label.equals("Spouse")) {
					actor.setSpouseName(value);
				} else if (label.equals("Parents")) {
					actor.setParents(value);
				} else if (label.equals("Children")) {
					actor.setChildren(value);
				} else if (label.equals("Website")) {
					actor.setWebsite(value);
				}
			}
		}

		return actor;
	}

	/*This method takes the file path as input reads the "infobox" from wiki page and returns that box content 
	 * as a list of strings
	 */
	public static ArrayList<ArrayList<String>> doWikiFetchingAndFormatting(
			String path, String type) {
		ArrayList<ArrayList<String>> listOfLabelsAndValues = new ArrayList<ArrayList<String>>();
		Parser parser = new Parser();
		HasAttributeFilter filter = null;
		if (type.equals("Movie")) {
			filter = new HasAttributeFilter("class", "infobox vevent");
		} else {
			filter = new HasAttributeFilter("class", "infobox biography vcard");

		}

		try {
			parser.setResource(path);
			NodeList listOfTablesWithCriteria = parser.parse(filter);
			NodeList trs = listOfTablesWithCriteria.extractAllNodesThatMatch(
					new TagNameFilter("tr"), true);
			for (int i = 0; i < trs.size(); i++) {
				ArrayList<String> singleLabelAndValue = new ArrayList<String>();
				NodeList nodes = trs.elementAt(i).getChildren();
				NodeList ths = nodes.extractAllNodesThatMatch(
						new TagNameFilter("th"), true);
				NodeList tds = nodes.extractAllNodesThatMatch(
						new TagNameFilter("td"), true);
				NodeList images = tds.extractAllNodesThatMatch(
						new TagNameFilter("img"), true);
				if (images.size() > 0) {
					continue;
				}
				for (int j = 0; (j < tds.size() || j < ths.size()); j++) {
					String thElement = ths.size() > 0 ? ths.asString() : "";
					String tdElement = tds.size() > 0 ? tds.asString() : "";
					thElement = DataFormatter.filterformatString(thElement);
					tdElement = DataFormatter.filterformatString(tdElement);
					singleLabelAndValue.add(thElement);
					singleLabelAndValue.add(tdElement);
					listOfLabelsAndValues.add(singleLabelAndValue);
				}
			}

		} catch (ParserException e) {
			e.printStackTrace();
		}
		return listOfLabelsAndValues;
	}

}
